# -*- coding: utf-8 -*-
"""
Module Description: redis的lua脚本执行器

封装使用evalsha的调用逻辑

Date: 2017/10/10
Author:Bai Jin Ping
"""
from redis.exceptions import NoScriptError

import redis_storage


# lua脚本的sha1校验码缓存
# {script: sha}
lua_script_sha_cache = {}


def _load_script(redis_conn, script):
    """
    加载脚本到redis, 缓存sha1校验码并返回
    :return: sha1
    """
    sha = redis_conn.script_load(script)
    lua_script_sha_cache[script] = sha
    return sha


def run_script_from_conn(redis_conn, script, numkeys, *keys_and_args):
    """
    在指定的redis连接上执行lua脚本
    :param redis_conn: redis连接
    :param script: lua脚本字符串
    :param numkeys: 脚本参数个数
    :param keys_and_args: 脚本参数
    :return:
    """
    sha = lua_script_sha_cache.get(script)
    if sha is not None:
        try:
            return redis_conn.evalsha(sha, numkeys, *keys_and_args)
        except NoScriptError:
            # redis不存在sha对应脚本缓存
            pass
    new_sha = _load_script(redis_conn, script)
    return redis_conn.evalsha(new_sha, numkeys, *keys_and_args)


def run_script_from_redis_name(redis_name, script, numkeys, *keys_and_args):
    """
    在指定名称的redis上执行lua脚本
    """
    redis_conn = redis_storage.RedisStorage.get_conn(redis_name)
    return run_script_from_conn(redis_conn=redis_conn, script=script, numkeys=numkeys, *keys_and_args)


if __name__ == '__main__':
    from redis import StrictRedis
    lua = "return 33333333"
    lua_script_sha_cache[lua] = 'test'
    conn = StrictRedis(host='192.168.7.12', port=6400)
    print run_script_from_conn(conn, lua, 0)
